#include "ffmuxerthread.h"
#include"muxer/ffmuxer.h"
#include"queue/ffapacketqueue.h"
#include"queue/ffvpacketqueue.h"
#include"encoder/ffaencoder.h"
#include"encoder/ffvencoder.h"
#include"queue/ffpacket.h"


FFMuxerThread::FFMuxerThread()
{

}

FFMuxerThread::~FFMuxerThread()
{

}

void FFMuxerThread::init(FFAPacketQueue *aPktQueue_, FFVPacketQueue *vPktQueue_, FFMuxer *muxer_, FFAEncoder *aEncoder_, FFVEncoder *vEncoder_)
{
    aPktQueue = aPktQueue_;
    vPktQueue = vPktQueue_;

    aEncoder = aEncoder_;
    vEncoder = vEncoder_;

    muxer = muxer_;
}

void FFMuxerThread::run() {
    bool audioFinish = false;
    bool videoFinish = false;

    muxer->writeHeader(); // 写入文件头（阻塞式，确保文件打开正常）

    FFPacket *audioPkt = nullptr;
    FFPacket *videoPkt = nullptr;
    AVPacket *aPacket = nullptr;
    AVPacket *vPacket = nullptr;

    while (!m_stop.load(std::memory_order_acquire)) {
        // ---------------------- 仅当未完成时获取音频数据包 ----------------------
        if (!audioFinish) {
            audioPkt = aPktQueue->dequeue();
            if (audioPkt == nullptr) {
                audioFinish = true; // 音频队列为空，强制完成
                continue; // 无数据，跳过本次处理
            }
            aPacket = &audioPkt->packet;
            // 计算音频PTS（单位：秒）
            double audioPtsSec = aPacket->pts * av_q2d(aEncoder->getCodecCtx()->time_base);
            audioFinish = (audioPtsSec >= 20.0); // 达到20秒标记完成

            std::cout<<"audio Finish:"<<audioPtsSec<<std::fixed<<std::endl;
        }

        // ---------------------- 仅当未完成时获取视频数据包 ----------------------
        if (!videoFinish) {
            videoPkt = vPktQueue->dequeue();
            if (videoPkt == nullptr) {
                videoFinish = true; // 视频队列为空，强制完成
                continue; // 无数据，跳过本次处理
            }
            vPacket = &videoPkt->packet;
            // 计算视频PTS（单位：秒）
            double videoPtsSec = vPacket->pts * av_q2d(vEncoder->getCodecCtx()->time_base);
            videoFinish = (videoPtsSec >= 20.0); // 达到20秒标记完成

            std::cout<<"video Finish:"<<videoPtsSec<<std::fixed<<std::endl;
        }

        // ---------------------- 处理逻辑（分四种情况） ----------------------
        // 情况1：两者都未完成（有有效数据）
        if (!audioFinish && !videoFinish) {
            processPacket(aPacket, audioPkt, vPacket, videoPkt);
        }
        // 情况2：仅音频未完成（视频已完成或无数据）
        else if (!audioFinish && aPacket) {
            processPacket(aPacket, audioPkt, nullptr, nullptr);
        }
        // 情况3：仅视频未完成（音频已完成或无数据）
        else if (!videoFinish && vPacket) {
            processPacket(nullptr, nullptr, vPacket, videoPkt);
        }
        // 情况4：两者都完成或无有效数据
        else {
            break; // 退出循环
        }

        // ---------------------- 重置指针（避免重复处理） ----------------------
        aPacket = nullptr;
        vPacket = nullptr;
    }

    // 写入文件尾部（确保资源释放）
    muxer->writeTrailer();

    // 释放自定义FFPacket指针（假设FFPacket是new出来的）
    av_freep(&audioPkt);
    av_freep(&videoPkt);
}

// 新增数据包处理函数（支持单流处理）
void FFMuxerThread::processPacket(AVPacket *aPkt, FFPacket *aFFPkt,
                                  AVPacket *vPkt, FFPacket *vFFPkt) {
    // 处理音频数据包（如果有效）
    if (aPkt && aFFPkt) {
        int ret = muxer->mux(aPkt);
        if (ret < 0) {
            m_stop.store(true, std::memory_order_release);
            std::cerr << "Mux audio packet failed, error: " << ret << std::endl;
        }
        // 释放音频资源
        av_packet_unref(aPkt);
        av_freep(&aFFPkt); // 释放FFPacket包装类
    }

    // 处理视频数据包（如果有效）
    if (vPkt && vFFPkt) {
        int ret = muxer->mux(vPkt);
        if (ret < 0) {
            m_stop.store(true, std::memory_order_release);
            std::cerr << "Mux video packet failed, error: " << ret << std::endl;
        }
        // 释放视频资源
        av_packet_unref(vPkt);
        av_freep(&vFFPkt); // 释放FFPacket包装类
    }

}

